﻿using Sustainalytics.Auth.Claims;
using Sustainalytics.BusinessResearchProductStates.Entities.ResearchState;
using Sustainalytics.Claims;
using Sustainalytics.ClientDW.Entities;
using Sustainalytics.Companies.Exceptions;
using Sustainalytics.Companies.Service.ErrorCodes;
using Sustainalytics.Companies.Service.Models;
using Sustainalytics.Companies.Service.Utility;
using Sustainalytics.DataLayer;
using Sustainalytics.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Claims;
using System.Web.Http;
using MongoDB.Driver;
using Sustainalytics.Entities.ProductInvolvement;
using System.Web.Http.Cors;
using Sustainalytics.Entities.SustainableProducts;
using Newtonsoft.Json;
using Sustainalytics.ClientDW.DataAccessLayer;

namespace Sustainalytics.Companies.Service.Controllers
{
    /// <summary>
    /// Company search API.
    /// </summary>
    //[AutoInvalidateCacheOutput]
    [EnableCors(origins: "*", headers: "*", methods: "*")]
    [LogControllerFilter(true, true, true)]
    [RoutePrefix("api/v1/companies")]
    public class CompaniesController : ApiController, ICompaniesController
    {
        private readonly ICompanyMatchingLogic _companyMatchingLogic;
        private static IClaimsChecker _claimsChecker;
        private readonly IMongoCollection<CorporateData> _corporateDataCollection;
        private readonly IMongoCollection<ProductInvolvementData> _piCompanyAssesmentCollection;
        private readonly IMongoCollection<SustainableProductsData> _sustainableProductsCollection;
        private readonly ICompaniesRepository _companySearchRepository;
        private readonly IUniversesRepository _universeRepository;

        static CompaniesController()
        {
            if (!UnitTestDetector.IsInUnitTest)
            {
                _claimsChecker = new ClaimsChecker();
            }
        }

        /// <summary>
        /// Ctor.
        /// </summary>
        public CompaniesController(
            ICompanyMatchingLogic companyMatchingLogic, 
            IClaimsChecker claimsChecker, 
            IMongoCollection<CorporateData> corporateDataCollection, 
            IMongoCollection<ProductInvolvementData> piCompanyAssesmentCollection,
            IMongoCollection<SustainableProductsData> sustainableProductsCollection,
            ICompaniesRepository companySearchRepository,
            IUniversesRepository universeRepository)
        {
            try
            {
                // log controller initialization
                CompaniesSerilog.Log.InitAccountsController();
                _companyMatchingLogic = companyMatchingLogic;
                _corporateDataCollection = corporateDataCollection;
                _piCompanyAssesmentCollection = piCompanyAssesmentCollection;
                _sustainableProductsCollection = sustainableProductsCollection;
                _claimsChecker = claimsChecker;
                _companySearchRepository = companySearchRepository;
                _universeRepository = universeRepository;
                CompaniesSerilog.Log.InitAccountsControllerSuccess();
            }
            catch (Exception ex)
            {
                CompaniesSerilog.Log.InitAccountsControllerError(ex);

                throw new HttpResponseException(HttpStatusCode.InternalServerError);
            }
        }

        // [CacheOutput(ServerTimeSpan = 100, ClientTimeSpan = 0, NoCache = true, MustRevalidate = true, Private = true)]
        [Route("{id}")]
        public HttpResponseMessage Get(int capitalIqId, AccountFeature feature = AccountFeature.CompanySearch, bool getResearchType = false)
        // public HttpResponseMessage Get(Guid id, AccountFeature feature = AccountFeature.CompanySearch, bool getResearchType = false)
        {
            try
            {
                if (getResearchType)
                {
                    //de luat luat capitalIqId din coporateData pt un guid
                    var corpData = GetCorporateDataById(capitalIqId);

                    var researchType = string.Empty;
                    if (corpData.ComprehensiveEsgResearchState.ResearchState == ResearchState.ResearchAvailable)
                        researchType = "Comprehensive";
                    if (corpData.CoreEsgResearchState.ResearchState == ResearchState.ResearchAvailable)
                        researchType = "Core";

                    return Request.CreateResponse(HttpStatusCode.OK, researchType);
                }

                var companyDto = GetCompanyById(capitalIqId, feature);

                return Request.CreateResponse(HttpStatusCode.OK, companyDto);
            }
            catch (CompanyNotFoundException)
            {
                return Request.CreateResponse(HttpStatusCode.NotFound);
            }
        }

        /// <summary>
        /// Search companies
        /// </summary>
        /// <param name="term"></param>
        /// <param name="pagingOptions"></param>
        /// <returns></returns>
        // [CacheOutput(ServerTimeSpan = 100, ClientTimeSpan = 0, NoCache = true, MustRevalidate = true, Private = true)]
        [Route("")]
        public HttpResponseMessage Get(
            [FromUri] string userId,
            [FromUri] string accountId,
            [FromUri] CompaniesListFilters filters,
            string term = null,
            int skip = 0,
            int take = 100,
            bool exactMatch = false,
            bool includeFullData = false,
            bool byFriendlyName = false,
            bool getCount = false,
            bool orderAscending = true,
            string orderBy = "CompanyNameLowercase",
            bool isGrid = false,
            bool fromAdmin = false,            
            AccountFeature accountFeature = AccountFeature.CompanySearch)
      {
            try
            {
                //var accountUniverses = ClaimsPrincipal.Current.Claims.GetUniverseIds(accountFeature);
                ClaimsIdentity claimsIdentity = (ClaimsIdentity)this.User.Identity;
                var accountUniverses = claimsIdentity.Claims.GetUniverseIds(accountFeature);
                //fail-safe mechanism: read account universes from db
                if(accountUniverses.Count == 0)
                {
                    var currentClaims = ClaimsPrincipal.Current.Claims;
                    var stringAccountId = currentClaims.Where(s => s.Type == CustomClaimTypes.AccountId)
                                                .Select(s => s.Value)
                                                .SingleOrDefault();
                    Guid accountGuid;
                    Guid.TryParse(stringAccountId, out accountGuid);
                    accountUniverses = _universeRepository.GetUniversesByAccountId(accountGuid).Select(p => p.Id).ToList();
                }

                if (getCount)
                {
                    // get companies paged
                    var count = GetCompanyCount(filters);

                    return Request.CreateResponse(HttpStatusCode.OK, new { companyCount = count });
                }

                if (fromAdmin)
                {
                    if (!_claimsChecker.ValidateCompanyAdminGovernanceClaim(this))
                        throw new CompanyAdminGovernanceClaimNull();

                    var companiesDtos = SearchCompany(accountUniverses, term, skip, take, true);
                    
                    return Request.CreateResponse(HttpStatusCode.OK, companiesDtos);
                }

                if (isGrid)
                {
                    List<CorporateData> companies = GetResearchGrid(filters, skip, take, orderAscending, orderBy);

                    // map companies to DTO
                    var companiesDtos = companies.Select(company => new CorporateDataDto().LoadLessCorporateData(
                        company, 
                        accountUniverses))
                        .ToList();

                    // return list of CorporateDataDto
                    return Request.CreateResponse(HttpStatusCode.OK, companiesDtos);
                }

                if (exactMatch == false)
                {
                    // SIMILARITY SEARCH
                    // get companies paged
                    var companiesDtos = SearchCompany(accountUniverses, term, skip, take);

                    return Request.CreateResponse(HttpStatusCode.OK, companiesDtos);
                }

                if (byFriendlyName)
                {
                    // EXACT SEARCH by FRIENDLY NAME
                    if (includeFullData && !_claimsChecker.ValidateCompanyOverviewClaim(this))
                        throw new CompanyOverviewClaimNull();
                    //GetCompanyByName
                    var companyDto = GetCompanyByNameUrlFriendly(term, accountFeature, includeFullData);

                    return Request.CreateResponse(HttpStatusCode.OK, companyDto); // returned CorporateDataExtendedDto
                }
                else
                {
                    // EXACT SEARCH
                    if (includeFullData && !_claimsChecker.ValidateCompanyOverviewClaim(this))
                        throw new CompanyOverviewClaimNull();

                    var companyDto = GetCompanyByName(term, accountFeature, includeFullData);

                    return Request.CreateResponse(HttpStatusCode.OK, companyDto);
                }
            }
            catch (CompanyAdminGovernanceClaimNull)
            {
                return Request.CreateResponse(HttpStatusCode.Forbidden, new { ErrorCode = CompaniesErrorCodes.CompanyAdminGovernanceClaimNull });
            }
            catch (CompanyOverviewClaimNull)
            {
                return Request.CreateResponse(HttpStatusCode.Forbidden, new { ErrorCode = CompaniesErrorCodes.CompanyOverviewClaimNull });
            }
            catch (CompanyNotFoundException)
            {
                return this.Request.CreateResponse(HttpStatusCode.NotFound);
            }
        }


        #region Methods added from CompaniesManager

        private CorporateData GetCorporateDataById(int capitalIqId)
        {
            try
            {
                CompaniesSerilog.Log.GetCompanyById(capitalIqId.ToString());

                var corporateData=_corporateDataCollection.Find(cd => cd.CapitalIqId == capitalIqId).SingleOrDefault();
               
                CompaniesSerilog.Log.GetCompanyByIdSuccess(capitalIqId.ToString());
                return corporateData;
            }
            catch (Exception ex)
            {
                CompaniesSerilog.Log.GetCompanyByIdError(capitalIqId.ToString(), ex);
                throw;
            }
        }
        private CorporateData GetCorporateDataById(int capitalIqId, bool includeFullData)
        {
            try
            {
                CorporateData corporateData;

                var filter = Builders<CorporateData>.Filter.Eq(cd => cd.CapitalIqId, capitalIqId);

                if (!includeFullData)
                {
                    corporateData = _corporateDataCollection.Find(filter)
                        .Project(cd => new CorporateData
                        {
                            Id = cd.Id,
                            UniverseIds = cd.UniverseIds,
                            CompanyName = cd.CompanyName,
                            CompanyNameLowercase = cd.CompanyNameLowercase,
                            CompanyNameUrlFriendly = cd.CompanyNameUrlFriendly,
                            Country = cd.Country,
                            PeerGroup = cd.PeerGroup,
                            MainExchange = cd.MainExchange,
                            MainTicker = cd.MainTicker,
                            ResearchParentId = cd.ResearchParentId,

                            SubPeerGroup = cd.SubPeerGroup,
                            BusinessDescription = cd.BusinessDescription,

                            ComprehensiveEsgResearchState = cd.ComprehensiveEsgResearchState,
                            CoreEsgResearchState = cd.CoreEsgResearchState,
                            RiskRatingResearchState = cd.RiskRatingResearchState,
                            CoreRiskResearchState = cd.CoreRiskResearchState,
                            SolutionsResearchState = cd.SolutionsResearchState,
                            ProductInvolvementResearchState = cd.ProductInvolvementResearchState,
                            GccsResearchState = cd.GccsResearchState,
                            CorporateGovernanceResearchState = cd.CorporateGovernanceResearchState,
                            ControversyResearchState = cd.ControversyResearchState
                        })
                        .FirstOrDefault();

                    return corporateData;
                }

                corporateData = _corporateDataCollection.Find(filter)
                    .Project(cd => new CorporateData
                    {
                        Id = cd.Id,
                        UniverseIds = cd.UniverseIds,
                        CompanyName = cd.CompanyName,
                        CompanyNameLowercase = cd.CompanyNameLowercase,
                        CompanyNameUrlFriendly = cd.CompanyNameUrlFriendly,
                        Country = cd.Country,
                        PeerGroup = cd.PeerGroup,

                        MainExchange = cd.MainExchange,
                        MainTicker = cd.MainTicker,
                        ResearchParentId = cd.ResearchParentId,

                        SubPeerGroup = cd.SubPeerGroup,
                        Address = cd.Address,
                        TotalEmployees = cd.TotalEmployees,
                        CompanyPhone = cd.CompanyPhone,
                        Website = cd.Website,
                        BusinessDescription = cd.BusinessDescription,


                        ComprehensiveEsgResearchState = cd.ComprehensiveEsgResearchState,
                        CoreEsgResearchState = cd.CoreEsgResearchState,
                        RiskRatingResearchState = cd.RiskRatingResearchState,
                        CoreRiskResearchState = cd.CoreRiskResearchState,
                        SolutionsResearchState = cd.SolutionsResearchState,
                        ProductInvolvementResearchState = cd.ProductInvolvementResearchState,
                        GccsResearchState = cd.GccsResearchState,
                        CorporateGovernanceResearchState = cd.CorporateGovernanceResearchState,
                        ControversyResearchState = cd.ControversyResearchState
                    })
                    .FirstOrDefault();

                return corporateData;
            }
            catch (Exception ex)
            {
                CompaniesSerilog.Log.GetCompanyByIdError(capitalIqId.ToString(), ex);
                throw;
            }
        }

        private CorporateDataDto GetCompanyById(int capitalIqId, AccountFeature feature)
        {
            try
            {
                CompaniesSerilog.Log.GetCompanyById(capitalIqId.ToString());

                var corporateData = GetCorporateDataById(capitalIqId, false);

                if (corporateData == null)
                {
                    throw new CompanyNotFoundException();
                }

                var accountUniverses = ClaimsPrincipal.Current.Claims.GetUniverseIds(feature);

                var companyDto = new CorporateDataDto();
                companyDto.LoadFrom(corporateData, accountUniverses);


                if (!corporateData.ResearchParentId.HasValue)
                {
                    CompaniesSerilog.Log.GetCompanyByIdSuccess(capitalIqId.ToString());

                    return companyDto;
                }


                companyDto = GetResearchData(corporateData, feature, false);

                CompaniesSerilog.Log.GetCompanyByIdSuccess(capitalIqId.ToString());

                return companyDto;
            }
            catch (Exception ex)
            {
                CompaniesSerilog.Log.GetCompanyByIdError(capitalIqId.ToString(), ex);

                throw;
            }
        }

        private CorporateDataDto GetResearchData(CorporateData coverageEntity, AccountFeature feature, bool includeFullData, bool hasProductInvolvementIndicators = false)
        {
            if (coverageEntity.ResearchParentId == null)
                throw new CompanyResearchCoverageNotFoundException();

            var research = GetCorporateDataById(_companyMatchingLogic.FindCapitalIqIdForGuid(coverageEntity.ResearchParentId.Value), includeFullData);
            if (research == null)
            {
                throw new CompanyResearchCoverageNotFoundException();
            }


            var accountUniverses = ClaimsPrincipal.Current.Claims.GetUniverseIds(feature);
            var companyDto = new CorporateDataDto();

            if (includeFullData == false)
            {
                companyDto.LoadFrom(research, accountUniverses, hasProductInvolvementIndicators);
            }
            else
            {
                companyDto.LoadFullCompany(research, accountUniverses, hasProductInvolvementIndicators);
            }


            companyDto.CompanyResearched = research.CompanyName;
            companyDto.IsCoverageEntity = true;
            companyDto.CoverageId = coverageEntity.Id;
            companyDto.CompanyName = coverageEntity.CompanyName;
            companyDto.Ticker = coverageEntity.MainTicker;
            companyDto.ExchangeCode = coverageEntity.MainExchange;
            companyDto.TickerAndExchange = (string.IsNullOrEmpty(coverageEntity.MainTicker) == false && string.IsNullOrEmpty(coverageEntity.MainExchange) == false)
                ? $"{coverageEntity.MainExchange}:{coverageEntity.MainTicker}"
                : null;

            return companyDto;
        }

        private int GetCompanyCount(CompaniesListFilters filters)
        {
            try
            {
                CompaniesSerilog.Log.CompanySearchCount(filters.CompanyNameLowerCase);
                // search for companies using repository              

                var count=_companySearchRepository.GetCompanyCount(filters);
               
                CompaniesSerilog.Log.CompanySearchCountSuccess(filters.CompanyNameLowerCase);

                return count;
            }
            catch (Exception ex)
            {
                CompaniesSerilog.Log.CompanySearchCountError(filters.CompanyNameLowerCase, ex);
                throw;
            }
        }

        private CorporateDataDto GetCompanyByName(string companyName, AccountFeature accountFeature, bool includeFullData)
        {
            try
            {
                CompaniesSerilog.Log.GetCompanyByName(companyName);
         
                var idcompanyMatch = _companyMatchingLogic.FindOneCompanyByIdentifier(IdentifierType.CompanyName ,companyName);
               
                var corporateData = GetCorporateDataById(idcompanyMatch, includeFullData);

                if (corporateData == null)
                {
                    throw new CompanyNotFoundException();
                }

                var accountUniverses = ClaimsPrincipal.Current.Claims.GetUniverseIds(accountFeature);

                var companyDto = new CorporateDataDto();

                if (includeFullData == false)
                {
                    companyDto.LoadFrom(corporateData, accountUniverses);
                }
                else
                {
                    companyDto.LoadFullCompany(corporateData, accountUniverses);
                }


                if (!corporateData.ResearchParentId.HasValue)
                {
                    CompaniesSerilog.Log.GetCompanyByNameSuccess(companyName);

                    return companyDto;
                }

                companyDto = GetResearchData(corporateData, accountFeature, includeFullData);

                CompaniesSerilog.Log.GetCompanyByNameSuccess(companyName);


                return companyDto;
            }
            catch (Exception ex)
            {
                CompaniesSerilog.Log.GetCompanyByNameError(companyName, ex);
                throw;
            }
        }

        private CorporateDataDto GetCompanyByNameUrlFriendly(string companyNameUrlFriendly, AccountFeature accountFeature, bool includeFullData)
        {
            try
            {
                CompaniesSerilog.Log.GetCompanyByNameUrlFriendly(companyNameUrlFriendly);
           
                var idcompanyMatched = _companyMatchingLogic.FindOneCompanyByIdentifier(IdentifierType.CompanyNameUrlFriendly,
                  companyNameUrlFriendly);

                 var corporateData = GetCorporateDataById(idcompanyMatched, includeFullData);

                if (corporateData == null)
                {
                    throw new CompanyNotFoundException();
                }

                var hasProductInvolvementIndicators = HasProductInvolvementIndicators(corporateData.ResearchParentId ?? corporateData.Id);
                var hasSustainableProductIndicators = HasSustainableProductsIndicators(corporateData.ResearchParentId ?? corporateData.Id);

                var accountUniverses = ClaimsPrincipal.Current.Claims.GetUniverseIds(accountFeature);

                var companyDto = new CorporateDataDto();

                if (!includeFullData)
                {
                    companyDto.LoadFrom(corporateData, accountUniverses, hasProductInvolvementIndicators, hasSustainableProductIndicators);
                }
                else
                {
                    companyDto.LoadFullCompany(corporateData, accountUniverses, hasProductInvolvementIndicators, hasSustainableProductIndicators);
                }


                if (!corporateData.ResearchParentId.HasValue)
                {
                    CompaniesSerilog.Log.GetCompanyByNameUrlFriendlySuccess(companyNameUrlFriendly);
                    return companyDto;
                }

                companyDto = GetResearchData(corporateData, accountFeature, includeFullData, hasProductInvolvementIndicators);

                CompaniesSerilog.Log.GetCompanyByNameUrlFriendlySuccess(companyNameUrlFriendly);

                return companyDto;
            }
            catch (Exception ex)
            {
                CompaniesSerilog.Log.GetCompanyByNameUrlFriendlyError(companyNameUrlFriendly, ex);

                throw;
            }
        }

        /// <summary>
        /// Search companies.
        /// </summary>
        /// <param name="accountUniverses"></param>
        /// <param name="term"> Search term. </param>
        /// <param name="skip"></param>
        /// <param name="take"></param>
        /// <param name="fromAdmin"></param>
        /// <returns> Paged list of companies. </returns>
        private List<CorporateDataDto> SearchCompany(List<int> accountUniverses, string term, int skip = 0, int take = 0, bool fromAdmin = false)
        {
            try
            {
               
                CompaniesSerilog.Log.CompanySearch(term, skip, take);
                
                // search for companies using controller
                var auxlist = (_companyMatchingLogic.MatchCompanies(skip, take, term)).Select(x => x.CompanyId).Distinct().ToList();
    
                var lst = GetCompaniesById(auxlist);

                if (fromAdmin)
                {
                    var companies = lst.Where(a => a.ResearchParentId == null).ToList();

                    // map companies to DTO
                    var dtos = companies.Select(company => new CorporateDataDto().LoadToAdmin(company)).ToList();

                    CompaniesSerilog.Log.CompanySearchSuccess(term, skip, take);

                    return dtos;
                }

                // map companies to DTO
                var companiesDtos = lst.Select(company => new CorporateDataDto().LoadFullCompany(company, accountUniverses)).ToList();

                CompaniesSerilog.Log.CompanySearchSuccess(term, skip, take);

                return companiesDtos;
            }
            catch (Exception ex)
            {
                // log company search error
                CompaniesSerilog.Log.CompanySearchError(term, skip, take, ex);

                throw;
            }
        }

        // private IEnumerable<CorporateData> GetCompaniesById(IEnumerable<Guid> ids)
        private IEnumerable<CorporateData> GetCompaniesById(List<int> ids)
        {
            var filter = Builders<CorporateData>.Filter.In(cd => cd.CapitalIqId, ids);

            var companies = _corporateDataCollection.Find(filter)
                .Project(cd => new CorporateData
                {
                    Id = cd.Id,
                    CompanyName = cd.CompanyName,
                    CompanyNameLowercase = cd.CompanyNameLowercase,
                    CompanyNameUrlFriendly = cd.CompanyNameUrlFriendly,
                    Country = cd.Country,
                    PeerGroup = cd.PeerGroup,
                    SubPeerGroup = cd.SubPeerGroup,

                    MainExchange = cd.MainExchange,
                    MainTicker = cd.MainTicker,
                    ResearchParentId = cd.ResearchParentId,
                    UniverseIds = cd.UniverseIds,
 
                    Address = cd.Address,
                    TotalEmployees = cd.TotalEmployees,
                    CompanyPhone = cd.CompanyPhone,
                    Website = cd.Website,
                    BusinessDescription = cd.BusinessDescription,

                    ComprehensiveEsgResearchState = cd.ComprehensiveEsgResearchState,
                    CoreEsgResearchState = cd.CoreEsgResearchState,
                    SolutionsResearchState = cd.SolutionsResearchState,
                    RiskRatingResearchState = cd.RiskRatingResearchState,
                    CoreRiskResearchState = cd.CoreRiskResearchState,
                    ProductInvolvementResearchState = cd.ProductInvolvementResearchState,
                    GccsResearchState = cd.GccsResearchState,
                    CorporateGovernanceResearchState = cd.CorporateGovernanceResearchState,
                    ControversyResearchState = cd.ControversyResearchState
                })
                .ToList();

            var companyIds = companies.Where(x => x.ResearchParentId.HasValue).Select(x => x.ResearchParentId.Value);

            var parentCompaniesDict = _corporateDataCollection.Find(Builders<CorporateData>.Filter.In(x => x.Id, companyIds))
                .Project(cd => new CorporateData
                {
                    Id = cd.Id,
                    PeerGroup = cd.PeerGroup,
                    SubPeerGroup = cd.SubPeerGroup
                })
                .ToList()
                .ToDictionary(x => x.Id, x => x);
            
            if (parentCompaniesDict.Any())
            {
                foreach (var comp in companies.Where(x => x.ResearchParentId.HasValue))
                {
                    if (parentCompaniesDict.TryGetValue(comp.ResearchParentId.Value, out CorporateData parentCompany))
                    {
                        comp.PeerGroup = parentCompany.PeerGroup;
                        comp.SubPeerGroup = parentCompany.SubPeerGroup;
                    }
                };
            }

            return companies;
        }

        private const string NotResearched = "Not researched";
        private bool HasProductInvolvementIndicators(Guid companyId)
        {
            var company = _piCompanyAssesmentCollection
                .Find(x => x.Id == companyId)
                .FirstOrDefault();

            return company != null && company.Indicators.Any(ind => ind.CategoryOfInvolvementType != NotResearched);
        }


        private bool HasSustainableProductsIndicators(Guid companyId)
        {
            var company = _sustainableProductsCollection
                .Find(x => x.Id == companyId)
                .FirstOrDefault();

            return company != null && company.Indicators.Any(ind => ind.CategoryOfInvolvementType != NotResearched);
        }

        //string term
        private List<CorporateData> GetResearchGrid(CompaniesListFilters filters, int skip = 0, int take = 100, bool orderAscending = true, string orderBy = "CompanyNameLowercase")
        {
            try
            {
                CompaniesSerilog.Log.CompanyGrid(filters.CompanyNameLowerCase, skip, take);

                // search for companies using repository

                var companies = _companySearchRepository.GetResearchGrid(filters, skip, take, orderAscending, orderBy);

                CompaniesSerilog.Log.CompanyGridSuccess(filters.CompanyNameLowerCase, skip, take);

                return companies;
            }
            catch (Exception ex)
            {
                CompaniesSerilog.Log.CompanyGridError(filters.CompanyNameLowerCase, skip, take, ex);
                throw;
            }
        }



        #endregion
    }
}
